from pymysql import cursors
import pymysql


class ReadMysql:
    """
    里面包含了对数据库进行增删改查的几个方法
    需要给定sql语句字符串
    根据sql字符串类型返回对应的结果
    增，删，改 返回影响行数 int数据
    查询返回 - 结果集
    a)所有结果集
    b)返回一行数据
    c)返回指定行数的数据
    d)返回一个单元格的数据
    """

    def __init__(self, user, password, database, host='localhost', port=3306):
        """
        创建对象时需要给定几个参数
        :param host: 地址 默认为本机
        :param user: 数据库用户名
        :param password: 数据库密码
        :param database: 数据库的名字
        :param port: 端口号，默认为3306
        """
        self.__con = pymysql.Connection(host=host,
                                        user=user,
                                        password=password,
                                        database=database,
                                        port=port,
                                        cursorclass=pymysql.cursors.DictCursor)
        self.__cur = self.__con.cursor()

    def add(self):
        sqlstr = "insert into student(sname,ssex,sbirthday,sid,class_no) values(%s,%s,%s,%s,%s)"
        sqldata = ('慕容复', '男', '1999-9-9', '121212123412341234', '001')
        # 执行sql - 可能因为sql语句错误导致异常
        try:
            row = self.__cur.execute(sqlstr, sqldata)
            print(row)
            # 因为sql是添加语句所以需要提交 - 增删改语句需要提交
            if row > 0:
                self.__con.commit()
        except Exception as e:
            print(e)
            print("[sqlstr error:]", sqlstr)

    def delete(self):
        sqlstr = 'delete from 表名 where 条件'
        try:
            row = self.__cur.execute(sqlstr)
            print(row)
            # 因为sql是添加语句所以需要提交 - 增删改语句需要提交
            if row > 0:
                self.__con.commit()
        except Exception as e:
            print(e)
            print("[sqlstr error:]", sqlstr)

    def update(self):
        sqlstr = 'update 表名 set  字段名=值，字段名=值 where 条件'
        try:
            row = self.__cur.execute(sqlstr)
            print(row)
            # 因为sql是添加语句所以需要提交 - 增删改语句需要提交
            if row > 0:
                self.__con.commit()
        except Exception as e:
            print(e)
            print("[sqlstr error:]", sqlstr)

    def select(self):
        # 写sql语句，查询所有信息
        sqlstr = "select * from student"
        try:
            # 执行可能因为sql语句错误导致异常
            row = self.__cur.execute(sqlstr)
            print(row)
            # 获取查询结果
            res = self.__cur.fetchall()
            return res
        except Exception as e:
            print(e)
            print("[sqlstr error:]", sqlstr)


class DBTools:
    """
    里面包含了对数据库进行增删改查的几个方法
    需要给定sql语句字符串
    根据sql字符串类型返回对应的结果
    增，删，改 返回影响行数 int数据
    查询返回 - 结果集
    a)所有结果集
    b)返回一行数据
    c)返回指定行数的数据
    d)返回一个单元格的数据
    """
    __conn = None  # 数据库链接通道

    @classmethod
    def __con(cls):
        cls.__conn = pymysql.Connection(
            host="localhost",
            user="root",
            password="123456",
            database="test",
            port=3306,
            cursorclass=pymysql.cursors.DictCursor)

    @classmethod
    def __execute_sql(cls, sql_str, par_ms=None):
        cls.__con()  # 获取链接通道
        sql_str = sql_str.lower()
        return_res = None
        try:
            with cls.__conn.cursor() as curs:
                return_res = curs.execute(sql_str, par_ms)
                if sql_str.split()[0] == 'select':
                    return_res = curs.fetchall()
                else:
                    if return_res > 0:
                        cls.__conn.commit()
        except Exception as e:
            print(e)
            print('【sql str】', sql_str)
            print('【sql data】', par_ms)
        finally:
            cls.__conn.close()  # 关闭链接通道对象
            return return_res  # 返回执行sql之后的结果

    @classmethod
    def insert(cls, sql, sql_date=None):
        return cls.__execute_sql(sql, sql_date)

    @classmethod
    def delete(cls, sql, sql_date=None):
        return cls.__execute_sql(sql, sql_date)

    @classmethod
    def update(cls, sql, sql_date=None):
        return cls.__execute_sql(sql, sql_date)

    @classmethod
    def fetchall(cls, sql, sql_date=None):
        return cls.__execute_sql(sql, sql_date)

    @classmethod
    def fetchone(cls, sql, sql_date=None):
        res = cls.__execute_sql(sql, sql_date)
        if res is not None and len(res) > 0:
            return res[0]


if __name__ == '__main__':
    print(DBTools.fetchone('select * from student'))
    print(DBTools.fetchall('select * from student'))
    print(DBTools.delete("insert into student(sno,sname,ssex,sbirthday,shenfenid,cno) values(%s,%s,%s,%s,%s,%s)",
                         ('s200', '慕容复', '男', '1999-9-9', '121212123412341234', '001')))
